from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.contrib import auth
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.core import exceptions

from math import floor, ceil
from datetime import date, timedelta

from forms import *

from timesheet.models import *
from manager.models import ProjectManager as PManager
from financier.models import Financier

from functions import *


def redirect_to_login(request):
    """
        This view carries out a redirection on page of authorisation or on
        page of the user (if he is authorised) by default.
        
    """
    if request.user.is_authenticated():
        return HttpResponseRedirect(reverse('user'))
    return HttpResponseRedirect(reverse('auth_login'))


def logout(request):
    auth.logout(request)
    return HttpResponseRedirect(reverse('auth_login'))


def redirect_to_complete(request):
    """
        This representation carries out a redirection on page for completation
        of the data entered by the user. In URL on redirect page number of
        current week of the user since first year is substituted.  

    """
    today_week = floor((date.today().toordinal() - 1)/7.)
    return HttpResponseRedirect('%s/' % int(today_week))


def user_redirect(request, template_user_begin='user_begin.html'):
    """
        This representation carries out a redirection on page for
        filling timesheet. In URL on redirection page number of last
        edited day of the user is substituted.
        If records is demanded to enter the first record.
        
    """
    if request.user.is_authenticated():
        if (Time.objects.take_time_not_complete(request.user.id).count() != 0):
            days = Date.objects.take_dates(request.user.id)
            day = days[len(days)-1]
            return HttpResponseRedirect("%s/" % day)
        else:
            id_user = request.user.id
            user = request.user
            is_financier = Financier.is_financier(user)
            is_manager = PManager.is_manager(user)
            activity_form = ActivityForm()
            projects = Project.objects.take_projects(id_user)
            projects_form = ProjectsForm(projects)
            today = date.today()
            date_form = DateForm({'date': date(today.year, today.month, today.day)})
            time_form = TimeForm()
            css_media = UserMediaForm()
            first_name = request.user.first_name
            last_name = request.user.last_name
            if (request.method == 'POST'):
                post = request.POST.copy()
                if 'time' in post:
                    activity_form = ActivityForm({'activities': post['activities']})
                    projects_form = ProjectsForm(projects, {'projects': post['projects']})
                    time_form = TimeForm({'time': post['time'], 'details': post['details']})
                    date_form = DateForm({'date': post['date']})
                    if ((activity_form.is_valid() == False) or (projects_form.is_valid() == False)
                        or (time_form.is_valid() == False) or (date_form.is_valid() == False)):
                        return render_to_response(template_user_begin,
                                                  {'activity_form': activity_form,
                                                   'projects_form': projects_form,
                                                   'date_form': date_form,
                                                   'first_name': first_name,
                                                   'last_name': last_name,
                                                   'css_media': css_media,
                                                   'date_form': date_form,
                                                   'time_form': time_form,
                                                   'is_financier': is_financier,
                                                   'is_manager': is_manager})
                    day = Date.take_date(date_form.cleaned_data['date'])
                    activity_project = ActivityProject.take_create_activityproject(
                                                                user, id_user, post,
                                             projects_form.cleaned_data['projects'],
                                             activity_form.cleaned_data['activities'])
                    try:
                        Time.objects.get(activity_project=activity_project,
                                         day=day)
                    except(Time.DoesNotExist):
                        Time.objects.create(activity_project=activity_project,
                                            time=time_form.cleaned_data['time'],
                                            details=time_form.cleaned_data['details'], day=day)
                    return HttpResponseRedirect(request.path)
            return render_to_response(template_user_begin,
                                      {'activity_form': activity_form,
                                       'projects_form': projects_form,
                                       'date_form': date_form,
                                       'first_name': first_name,
                                       'last_name': last_name,
                                       'css_media': css_media,
                                       'date_form': date_form,
                                       'time_form': time_form,
                                       'is_financier': is_financier,
                                       'is_manager': is_manager})

    else:
        return HttpResponseRedirect(reverse('invalid'))
    

def user(request, template_user='user_timesheet.html', day=''):
    """
        View for page of the user.
        
    """
    if request.user.is_authenticated():
        id_user = request.user.id
        user = request.user
        is_financier = Financier.is_financier(user)
        is_manager = PManager.is_manager(user)
        day = get_object_or_404(Date, day=day)
        activity_form = ActivityForm()
        projects = Project.objects.take_projects(id_user)
        projects_form = ProjectsForm(projects)
        date_form = DateForm({'date': day.day})
        time_form = TimeForm()
        css_media = UserMediaForm()
        times = Time.objects.take_time_with_day(id_user, day)
        count_time = len(times)
        first_name = request.user.first_name
        last_name = request.user.last_name
        if (len(times) == 0):
            raise Http404()
        if (request.method == 'POST'):
            post = request.POST.copy()
            if ('time' in post):
                activity_form = ActivityForm({'activities': post['activities']})
                projects_form = ProjectsForm(projects, {'projects': post['projects']})
                time_form = TimeForm({'time': post['time'], 'details': post['details']})
                date_form = DateForm({'date': post['date']})
                if ((activity_form.is_valid() == False) or (projects_form.is_valid() == False)
                    or (time_form.is_valid() == False) or (date_form.is_valid() == False)):
                    return render_to_response(template_user,
                                              {'activity_form': activity_form,
                                               'projects_form': projects_form,
                                               'date_form': date_form,
                                               'times': times,
                                               'first_name': first_name,
                                               'last_name': last_name,
                                               'day': day,
                                               'date_form': date_form,
                                               'time_form': time_form,
                                               'css_media': css_media,
                                               'is_financier': is_financier,
                                               'is_manager': is_manager})
                if (date_form.cleaned_data['date'] != str(day.day)):
                    day = Date.take_date(date_form.cleaned_data['date'])
                activity_project = ActivityProject.take_create_activityproject(
                                                            user, id_user, post,
                                         projects_form.cleaned_data['projects'],
                                         activity_form.cleaned_data['activities'])
                try:
                    Time.objects.get(activity_project=activity_project, day=day)
                except(Time.DoesNotExist):
                    Time.objects.create(activity_project=activity_project,
                                        time=time_form.cleaned_data['time'],
                                        details=time_form.cleaned_data['details'],
                                        day=day)
                return HttpResponseRedirect(reverse('user_day',
                                                    kwargs={'day': day.day}))
            if ('save_form' in post):
                Time.update_time_from_post(times, post)
                return HttpResponseRedirect(request.path)
            delete_time_id = find_delete_time(times, post)
            if delete_time_id:
                Time.objects.get(id=delete_time_id).delete()
                count_time -= 1
                day = day.day
                if (count_time == 0):
                    user_dates = Date.objects.take_dates(id_user)
                    count_dates = len(user_dates)
                    if (count_dates != 0):
                        day = user_dates[count_dates-1]
                    else:
                        return HttpResponseRedirect(reverse('user'))
                return HttpResponseRedirect(reverse('user_day',
                                                    kwargs={'day': day}))
        else:
            if (request.method == 'GET'):
                get = request.GET.copy()
                # We choose the necessary dates ' left ' shift for the previous date,
                # ' right ' on the following
                if ('left' in get):
                    days = Date.objects.take_dates(id_user)
                    index = Date.find_index_date(days, day.day)
                    try:
                        day_left = days[index-1]
                    except(AssertionError):
                        return HttpResponseRedirect(reverse('user_day',
                                                            kwargs={'day': days[len(days)-1]}))
                    return HttpResponseRedirect(reverse('user_day',
                                                        kwargs={'day': day_left}))
                elif ('right' in get):
                    days = Date.objects.take_dates(id_user)
                    index = Date.find_index_date(days, day.day)
                    try:
                        day_right = days[index+1]
                    except(IndexError):
                        return HttpResponseRedirect(reverse('user_day',
                                                            kwargs={'day': days[0]}))
                    return HttpResponseRedirect(reverse('user_day',
                                                        kwargs={'day': day_right}))
        return render_to_response(template_user, {'activity_form': activity_form,
                                                  'projects_form': projects_form,
                                                  'date_form': date_form,
                                                  'times': times,
                                                  'first_name': first_name,
                                                  'last_name': last_name,
                                                  'day': day,
                                                  'date_form': date_form,
                                                  'time_form': time_form,
                                                  'css_media': css_media,
                                                  'is_financier': is_financier,
                                                  'is_manager': is_manager})
    else:
        return HttpResponseRedirect(reverse('invalid'))


def user_week_complete(request,
                       template_user_week_complete='user_week_complete_timesheet.html',
                       number_week=((date.today().toordinal() - 1)/7.)):
    """
        View for page for completation of the entered data.
        
    """
    if request.user.is_authenticated():
        id_user = request.user.id
        css_media = CompletionMediaForm()
        number_week = int(number_week)
        try:
            begin_day = date.fromordinal(number_week*7 + 1)
        except(ValueError):
            raise Http404()
        list_day = get_dates(1, begin_day)
        end_day = begin_day + timedelta(days=6)
        if request.method == 'POST':
            post = request.POST.copy()
            if 'Save' in post:
                new_list = make_list_post(post)
                Time.save_time_in_completion(id_user, new_list)
                return HttpResponseRedirect(request.path)
            if 'Complete' in post:
                Time.objects.complete_time(id_user, begin_day, end_day)
                return HttpResponseRedirect(request.path)
        week_prev = reverse('user_week_complete',
                            kwargs={'number_week': number_week - 1})
        week_next = reverse('user_week_complete',
                            kwargs={'number_week': number_week + 1})
        times = Time.objects.take_all_time_day_interval(id_user,
                                                      begin_day,
                                                         end_day)
        data = convert_data_times(times, list_day) # Build the list of data for display in a template
        total_time_right = sum_total_time_right(data)
        total_time_down = sum_total_time_down(data)
        all_time = sum_total_time(total_time_down)
        if total_time_right != []:
            total_time_right = iter(total_time_right)
        return render_to_response(template_user_week_complete, {'css_media': css_media,
                                                                'data': data,
                                                                'all_time': all_time,
                                                                'list_day': list_day,
                                                                'total_time_down': total_time_down,
                                                                'total_time_right': total_time_right,
                                                                'week_prev': week_prev,
                                                                'week_next': week_next})
    else:
        return HttpResponseRedirect(reverse('invalid'))
